package com.stark.wechat.service.accesstoken;

import com.dtflys.forest.Forest;
import com.fasterxml.jackson.databind.JsonNode;
import com.stark.wechat.core.Config;
import com.stark.wechat.service.accesstoken.model.GetAccessTokenResponsePayload;
import com.stark.wechat.util.JacksonUtils;
import com.stark.wechat.util.ResponseUtils;
import lombok.Builder;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Access token 接口
 *
 * @author <a href="mailto:mengbin@hotmail.com">Ben</a>
 * @version 1.0.0
 * @see <a href="https://developers.weixin.qq.com/doc/service/api/base/api_getaccesstoken.html">基础接口 / 获取接口调用凭据</a>
 * @since 2024/5/23
 */
@Builder
public class AccessTokenService {

    /**
     * 公众号配置
     */
    private final Config config;

    /**
     * 获取访问令牌
     *
     * @return 响应
     * @see <a href="https://developers.weixin.qq.com/doc/service/api/base/api_getaccesstoken.html">基础接口 / 获取接口调用凭据</a>
     */
    public GetAccessTokenResponsePayload getAccessToken() {
        String responseStr = Forest
                .get(config.getWechatGateway() + "/cgi-bin/token")
                .addQuery("grant_type", "client_credential")
                .addQuery("appid", config.getAppId())
                .addQuery("secret", config.getAppSecret())
                .connectTimeout(config.getConnectTimeout())
                .readTimeout(config.getReadTimeout())
                .contentTypeJson()
                .executeAsString();
        JsonNode root = JacksonUtils.readTree(responseStr);
        ResponseUtils.findError("获取访问令牌失败", root, CODE_MAP.get("getAccessToken"));
        return JacksonUtils.deserialize(responseStr, GetAccessTokenResponsePayload.class);
    }

    private static final Map<String, Map<Long, String>> CODE_MAP;

    static {
        CODE_MAP = new HashMap<>();

        Map<Long, String> codeMap = new HashMap<>();
        codeMap.put(-1L, "系统繁忙，请稍候再试");
        codeMap.put(40001L, "获取 access_token 时 AppSecret 错误，或者 access_token 无效");
        codeMap.put(40002L, "不合法的凭证类型");
        codeMap.put(40013L, "不合法的 AppID");
        codeMap.put(40125L, "不合法的 secret");
        codeMap.put(40164L, "调用接口的IP地址不在白名单中");
        codeMap.put(40243L, "AppSecret已被冻结，请解冻后再次调用");
        codeMap.put(41004L, "缺少 secret 参数");
        codeMap.put(50004L, "禁止使用 token 接口");
        codeMap.put(50007L, "账号已冻结");
        CODE_MAP.put("getAccessToken", Collections.unmodifiableMap(codeMap));
    }

}
